<!--
 * @Author: luobei luobei@seewintech.com
 * @Date: 2023-02-23 20:11:19
 * @LastEditors: luobei luobei@seewintech.com
 * @LastEditTime: 2023-02-27 11:50:58
 * @FilePath: \ibuilds-web-system\src\views\systemManage\formManage\formDesign\packages\config\tree.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
  <div>
    <el-form-item label="占位内容">
      <el-input v-model="data.placeholder" clearable placeholder="占位内容" />
    </el-form-item>
    <div class="el-form-item el-form-item--small el-form--label-top">
      <label class="el-form-item__label" style="padding: 0">字典配置：</label>
      <div class="el-form-item__content">
        <el-tabs v-model="data.dicOption" stretch @tab-click="handleTabClick">
          <el-tab-pane label="静态数据" name="static">
            <el-tree
              ref="tree"
              :data="data.dicData"
              default-expand-all
              draggable
              node-key="value"
              :expand-on-click-node="false"
            >
              <span slot-scope="scope" class="custom-tree-node">
                <span>{{ scope.node.label }}</span>
                <span>
                  <el-button
                    type="text"
                    size="mini"
                    icon="el-icon-plus"
                    @click="handleNodeAdd(scope.data)"
                  />
                  <!--                <el-button class="warning" type="text" size="mini" icon="el-icon-edit"-->
                  <!--                           @click="handleNodeEdit(data)"></el-button>-->
                  <el-button
                    class="danger"
                    type="text"
                    size="mini"
                    icon="el-icon-delete"
                    @click="handleNodeRemove(scope.node, scope.data)"
                  />
                </span>
              </span>
            </el-tree>
            <div style="margin-left: 22px">
              <el-button type="text" size="small" @click="handleParentNodeAdd">
                添加父级
              </el-button>
            </div>
          </el-tab-pane>
          <el-tab-pane label="远端数据" name="remote">
            网址
            <el-input
              v-model="data.dicUrl"
              size="small"
              placeholder="远端数据字典网址"
            />
            远程搜索
            <el-switch v-model="data.remote" />
            <br />
            请求方法
            <el-select
              v-model="data.dicMethod"
              size="small"
              placeholder="请求方法"
              style="width: 100%"
            >
              <el-option label="POST" value="post" />
              <el-option label="GET" value="get" />
            </el-select>
            <p v-if="data.dicMethod == 'post'">
              请求参数
              <avue-dynamic v-model="data.dicQueryConfig" :children="option" />
            </p>
            <p v-if="data.dicUrl">
              返回结构
              <monaco-editor
                v-model="dicFormatter"
                height="80"
                :key-index="`dict-formatter-${data.prop}`"
                :options="options"
              />
            </p>
            <div class="el-form-item el-form-item--small el-form--label-top">
              <label class="el-form-item__label" style="padding: 0">
                字典key配置：
              </label>
              <div class="el-form-item__content">
                <ul>
                  <li v-for="(value, key) in data.props" :key="key">
                    <span style="width: 50px">{{ key }}</span>
                    <el-input
                      v-model="data.props[key]"
                      size="mini"
                      placeholder="key配置"
                    />
                  </li>
                </ul>
              </div>
            </div>
          </el-tab-pane>
        </el-tabs>
      </div>
    </div>
    <!-- <el-form-item v-if="data.dicOption == 'remote'" label="重新请求字典(crud)">
      <el-switch v-model="data.dicFlag" />
    </el-form-item> -->
    <!-- <div class="el-form-item el-form-item--small el-form--label-top">
      <label class="el-form-item__label" style="padding: 0">级联配置：</label>
      <div class="el-form-item__content">
        <draggable
          tag="ul"
          :list="data.cascaderItem || data.cascader"
          :group="{ name: 'cascaderItem' }"
          ghost-class="ghost"
          handle=".drag-item"
        >
          <li
            v-for="(item, index) in data.cascaderItem || data.cascader"
            :key="index"
          >
            <i
              class="drag-item el-icon-s-operation"
              style="font-size: 16px; margin: 0 5px; cursor: move"
            />
            <el-input
              v-if="avueVersion('2.9.0')"
              v-model="data.cascaderItem[index]"
              size="mini"
              clearable
              placeholder="级联属性值"
            />
            <el-input
              v-else
              v-model="data.cascader[index]"
              size="mini"
              clearable
              placeholder="级联属性值"
            />
            <el-button
              circle
              plain
              type="danger"
              size="mini"
              icon="el-icon-minus"
              style="padding: 4px; margin-left: 5px"
              @click="handleRemoveCascaderItemFields(index)"
            />
          </li>
        </draggable>
        <div style="margin-left: 22px">
          <el-button type="text" size="small" @click="handleAddCascaderItemFields">
            添加列
          </el-button>
        </div>
      </div>
    </div> -->
    <template v-if="data.type == 'tree'">
      <el-form-item label="当有子级时,是否可选择父级" label-width="200px">
        <el-switch v-model="data.parent" />
      </el-form-item>
    </template>
    <template v-if="data.type == 'cascader'">
      <el-form-item label="选项分隔符" label-width="100px">
        <el-input v-model="data.separator" clearable placeholder="选项分隔符" />
      </el-form-item>
      <el-form-item label="是否显示选中值的完整路径" label-width="200px">
        <el-switch v-model="data.showAllLevels" />
      </el-form-item>
      <el-form-item label="是否可搜索" label-width="100px">
        <el-switch v-model="data.filterable" />
      </el-form-item>
    </template>
    <el-form-item label="是否多选">
      <el-switch v-model="data.multiple" />
    </el-form-item>
    <el-form-item
      v-if="data.type == 'tree' && data.multiple"
      label="勾选时，父子不关联"
      label-width="160px"
    >
      <el-switch v-model="data.checkStrictly" />
    </el-form-item>

    <el-dialog
      :visible.sync="dialogVisible"
      :rules="dialogRules"
      :before-close="beforeClose"
    >
      <el-form ref="dialogForm" :model="dialogForm" label-width="80px">
        <el-form-item label="label">
          <el-input v-model="dialogForm.label" placeholder="label" />
        </el-form-item>
        <el-form-item label="value">
          <el-input
            v-model="dialogForm.value"
            placeholder="value"
            :type="dialogInputType"
          >
            <el-select
              slot="append"
              v-model="dialogInputType"
              placeholder="数据类型"
              style="width: 100px"
            >
              <el-option label="String" value="text" />
              <el-option label="Number" value="number" />
            </el-select>
          </el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button
          v-if="dialogStatus == 'add'"
          type="primary"
          @click="handleDialogAdd"
        >
          确 定
        </el-button>
        <!--        <el-button type="primary" @click="handleDialogUpdate" v-else>确 定</el-button>-->
      </span>
    </el-dialog>
  </div>
</template>
<script>
  import MonacoEditor from '../utils/monaco-editor'
  import Draggable from 'vuedraggable'

  export default {
    name: 'ConfigTree',
    components: { MonacoEditor, Draggable },
    props: ['data'],
    data() {
      return {
        dialogForm: {},
        dialogVisible: false,
        dialogRules: {
          label: { required: true, message: '请输入label' },
          value: { required: true, message: '请输入value' },
        },
        dialogStatus: 'add',
        selectData: undefined,
        dialogInputType: 'text',
        option: {
          column: [
            {
              type: 'input',
              prop: 'key',
              label: 'key',
            },
            {
              type: 'input',
              prop: 'value',
              label: 'value',
            },
          ],
        },
        options: {
          fullScreen: true,
          minimap: {
            enabled: false,
          },
        },
        dicFormatter: '',
      }
    },
    watch: {
      'data.prop': {
        handler() {
          if (!this.avueVersion('2.9.0') && this.data.cascaderItem) {
            this.$set(this.data, 'cascader', this.data.cascaderItem)
            this.$delete(this.data, 'cascaderItem')
          }
          const { dicFormatter } = this.data
          this.dicFormatter = dicFormatter
            ? dicFormatter + ''
            : '(res) => {\r\n  return res.data\r\n}'
        },
        immediate: true,
      },
      dicFormatter: {
        handler(val) {
          try {
            this.data.dicFormatter = eval(val)
          } catch (e) {
            // console.error(e)
          }
        },
      },
    },
    methods: {
      handleRemoveCascaderItemFields(index) {
        if (this.avueVersion('2.9.0')) this.data.cascaderItem.splice(index, 1)
        else this.data.cascader.splice(index, 1)
      },
      handleAddCascaderItemFields() {
        if (this.avueVersion('2.9.0')) {
          if (!this.data.cascaderItem) {
            this.$set(this.data, 'cascaderItem', [])
          }
          this.data.cascaderItem.push('')
        } else {
          if (!this.data.cascader) {
            this.$set(this.data, 'cascader', [])
            delete this.data.cascaderItem
          }
          this.data.cascader.push('')
        }
      },
      handleTabClick({ name }) {
        if (name === 'remote' && !this.data.dicQueryConfig) {
          this.data.dicQueryConfig = []
        }
      },
      handleParentNodeAdd() {
        this.selectData = undefined
        this.dialogStatus = 'add'
        this.dialogVisible = true
      },
      handleNodeAdd(data) {
        this.selectData = data
        this.dialogStatus = 'add'
        this.dialogVisible = true
      },
      handleNodeRemove(node, data) {
        const parent = node.parent
        const children = parent.data.children || parent.data
        const index = children.findIndex((d) => d.value === data.value)
        children.splice(index, 1)
      },
      handleDialogAdd() {
        this.$refs.dialogForm.validate((valid) => {
          if (valid) {
            const { label, value } = this.dialogForm
            const node = this.$refs.tree.getNode(value)
            if (node) this.$message.error('value重复')
            else {
              const data = this.selectData
              const newNode = {
                label,
                value:
                  this.dialogInputType === 'number' ? Number(value) : value,
              }
              if (data) {
                if (!data.children) this.$set(data, 'children', [])
                data.children.push(newNode)
              } else {
                this.$set(this.data.dicData, this.data.dicData.length, newNode)
              }
              this.beforeClose()
            }
          }
        })
      },
      beforeClose() {
        this.$refs.dialogForm?.clearValidate()
        this.dialogForm = {}
        this.dialogVisible = false
      },
    },
  }
</script>
<style lang="less" scoped>
  .custom-tree-node {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 14px;
    padding-right: 8px;
  }
</style>
